home *** CD-ROM | disk | FTP | other *** search
- ; Shift and Rotate Instructions
-
- .386 ;So we can use extended registers
- option segment:use16 ; and addressing modes.
-
- dseg segment para public 'data'
-
- ; The following structure holds the bit values for an 80x86 mod-reg-r/m byte.
-
- mode struct
- modbits byte ?
- reg byte ?
- rm byte ?
- mode ends
-
- Adrs1 mode {11b, 100b, 111b}
- modregrm byte ?
-
- var1 word 1
- var2 word 8000h
- var3 word 0FFFFh
- var4 word ?
-
- dseg ends
-
- cseg segment para public 'code'
- assume cs:cseg, ds:dseg
-
- Main proc
- mov ax, dseg
- mov ds, ax
- mov es, ax
-
- ; Shifts and rotates directly on memory locations:
- ;
- ; var1 := var1 shl 1
-
- shl var1, 1
-
- ; var1 := var1 shr 1
-
- shr var1, 1
-
- ; On 80286 and later processors, you can shift by more than one bit at
- ; at time:
-
- shl var1, 4
- shr var1, 4
-
- ; The arithmetic shift right instruction retains the H.O. bit after each
- ; shift. The following SAR instruction sets var2 to 0FFFFh
-
- sar var2, 15
-
- ; On all processors, you can specify a shift count in the CL register.
- ; The following instruction restores var2 to 8000h:
-
- mov cl, 15
- shl var2, cl
-
- ; You can use the shift and rotate instructions, along with the logical
- ; instructions, to pack and unpack data. For example, the following
- ; instruction sequence extracts bits 10..13 of var3 and leaves
- ; this value in var4:
-
- mov ax, var3
- shr ax, 10 ;Move bits 10..13 to 0..3.
- and ax, 0Fh ;Keep only bits 0..3.
- mov var4, ax
-
- ; You can use the rotate instructions to compute this value somewhat faster
- ; on older processors like the 80286.
-
- mov ax, var3
- rol ax, 6 ;Six rotates rather than 10 shifts.
- and ax, 0Fh
- mov var4, ax
-
- ; You can use the shift and OR instructions to easily merge separate fields
- ; into a single value. For example, the following code merges the mod, reg,
- ; and r/m fields (maintained in separate bytes) into a single mod-reg-r/m
- ; byte:
-
-
- mov al, Adrs1.modbits
- shl al, 3
- or al, Adrs1.reg
- shl al, 3
- or al, Adrs1.rm
- mov modregrm, al
-
- ; If you've only got and 8086 or 8088 chip, you'd have to use code like the
- ; following:
-
- mov al, Adrs1.modbits ;Get mod field
- shl al, 1
- shl al, 1
- or al, Adrs1.reg ;Get reg field
- mov cl, 3
- shl al, cl ;Make room for r/m field.
- or al, Adrs1.rm ;Merge in r/m field.
- mov modregrm, al ;Save result away.
-
- Quit: mov ah, 4ch ;DOS opcode to quit program.
- int 21h ;Call DOS.
- Main endp
-
- cseg ends
-
- sseg segment para stack 'stack'
- stk byte 1024 dup ("stack ")
- sseg ends
-
- zzzzzzseg segment para public 'zzzzzz'
- LastBytes byte 16 dup (?)
- zzzzzzseg ends
- end Main
-